import Doc from '~/components/layout/docs'
import Link from '~/components/text/link'
import Snippet from '~/components/snippet'
import { InlineCode } from '~/components/text/code'
import Caption from '~/components/text/caption'
import Card from '~/components/card'
import Note from '~/components/text/note'

export const meta = {
  title: 'Serverless Functions',
  description: 'Learn how to deploy Serverless Functions with ZEIT Now.',
  editUrl: 'pages/docs/v2/serverless-functions/introduction.mdx',
  lastEdited: '2020-01-24T10:37:14.000Z'
}

With ZEIT Now, you can deploy Serverless Functions, which are pieces of code written with [backend languages](/docs/v2/serverless-functions/supported-languages/#supported-languages) that take an HTTP request and provide a response.

You can use Serverless Functions to handle user authentication, form submission, database queries, custom
slack commands, and more.

## Creating Serverless Functions

To create a Serverless Function, create a file in an `/api` directory from your project root with the appropriate language extension.

<Note>
  If you are using Next.js, use the <InlineCode>/pages/api</InlineCode>{' '}
  directory instead.
  <br />
  <Link href="https://nextjs.org/docs#api-routes">
    Read more about API functionality with Next.js
  </Link>
  .
</Note>

For example, to create a TypeScript function, you can create a file called `get-user.ts` like below.

```ts
import { NowRequest, NowResponse } from '@now/node'

export default (req: NowRequest, res: NowResponse) => {
  res.json({ name: 'John', email: 'john@example.com' })
}
```

<Caption>
  A TypeScript Serverless Function that returns a JSON response.
</Caption>

When a user visits `/api/get-user`, they will receive the JSON from above. Note that you don't have to explicitly set up any routing rules for this to work. By default, [filesystem routing](https://zeit.co/docs/configuration/#routes) is leveraged.

## Deploying Serverless Functions

To deploy Serverless Functions without any additional configuration, you can put files with extensions matching [supported languages](/docs/v2/serverless-functions/supported-languages) and exported functions in the `/api` directory at your project's root.

<Note>
  If you are using Next.js, use the <InlineCode>/pages/api</InlineCode>{' '}
  directory instead.
  <br />
  <Link href="https://nextjs.org/docs#api-routes">
    Read more about API functionality with Next.js
  </Link>
  .
</Note>

Then, push to your connected Git repository using a [ZEIT Now for Git Integration](/docs/v2/git-integrations) to receive a deployment automatically.

### An Example Node.js Serverless Function

To deploy a [serverless Node.js API](/docs/v2/serverless-functions/supported-languages#node.js), provide a main export function like the following, in a `.js` file within the `/api` directory:

```js
module.exports = (req, res) => {
  res.json({
    body: req.body,
    query: req.query,
    cookies: req.cookies
  })
}
```

<Caption>
  An example Node.js Serverless Function using Express.js-like helper methods
  from the{' '}
  <Link href="/docs/v2/serverless-functions/supported-languages#node.js-request-and-response-objects">
    Request and Response objects
  </Link>
  .
</Caption>

The above example echoes the `body`, path `query`, and `cookie`s, passed with the request object, as a JSON object using helper methods provided through the [Request and Response](/docs/v2/serverless-functions/supported-languages/#node.js-request-and-response-objects).

Then, all you need to do, to have a live API, is push to your connected Git repository using a [ZEIT Now for Git Integration](/docs/v2/git-integrations) to receive a deployment automatically.

The resulting deployment will contain your Node.js Serverless Function and will provide you with a URL like the following, with your API ready to go: <https://node-echo-api.now-examples.now.sh/api/?name=zeit>

### More Examples and Supported Languages

For all supported languages, see the [Supported Languages for Serverless Functions documentation](/docs/v2/serverless-functions/supported-languages).

More examples of applications you can deploy paired with Serverless Functions can be found in the [ZEIT Now repository on GitHub](https://github.com/zeit/now/tree/master/examples).

You can get started with many of the ZEIT Now examples by deploying them from the [Quickstarts section](/docs/v2/introduction#quickstarts).

## Prevent Endpoint Listing

By default, all files inside of the `/api` directory will be made available as Serverless Functions.

If this behavior is not desired, for example you want a utilities folder inside of the `/api` directory, you can prefix files or folders with either `_` or `.` to prevent them from being created as Serverless Functions.

Therefore, if you keep your utility functions inside of `/api/_utils`, none of them will be created as Serverless Functions. This is because the parent folder is prefixed with `_`.

If you kept your utility functions inside of `/api/utils`, one called `date.js` and the other `_time.js`, only `date.js` would be created as a Serverless Function.

## Path Segments

Deploying Serverless Functions with ZEIT Now gives you the ability to use path segments through file names instead of a complex routes file.

Creating a file using any of the [supported languages](/docs/v2/serverless-functions/supported-languages) in the `/api` directory and wrapping the filename in square brackets, such as `[name].js` will provide you with a file that takes a path segment and gives it to the function when requested with a value.

<Note>
  When using path segments, the value passed is made available to the{' '}
  <InlineCode>req.query</InlineCode> object under the key used for the file
  name.
</Note>

When using path segments, **any dynamic filename can be used**, this is indicated by the use of square brackets. The filename for the path segment is used solely for the purpose of providing a key name for accessing the value on the `req.query` object.

For example, creating a `name` directory (within `/api`) that contains a `[name].js` file will allow you to receive the path segment entered when accessing `/api/name/your-name` on the `req.query.name` object.

The following Node.js example code could then use the path segment in its functionality when requested:

```js
module.exports = (req, res) => {
  const {
    query: { name }
  } = req

  res.send(`Hello ${name}!`)
}
```

<Caption>
  An example of a Node.js Serverless Function that takes a name path segment and
  returns a string using it.
</Caption>

The resulting deployment can be found here: <https://path-segment-with-node.now-examples.now.sh/api/name/world>

<Note>
  Any{' '}
  <Link href="/docs/v2/serverless-functions/supported-languages">
    supported language
  </Link>{' '}
  can utilize path segments.
</Note>

## Local Development

ZEIT Now provides an additional command with [Now CLI](/download) to help you develop Serverless Functions locally by replicating the production environment on ZEIT Now with your localhost.

If you have an `api` directory like the [above examples](#deploying-serverless-functions) on this page, you can run the following command to start a local development environment that supports your serverless API and allows you to develop locally, just make sure to install your project's dependencies first with `npm install`:

<Snippet dark text="now dev" />
<Caption>Starting a local development environment using Now CLI, for Serverless Functions.</Caption>

<Note>
  The <InlineCode>now dev</InlineCode> command is still in beta. If you have any
  feedback, <Link href="https://zeit.co/feedback/dev">please let us know</Link>.
</Note>

If you have a statically generated frontend that supports its own development environment, such as Next.js, we recommend creating a `dev` script within a `package.json` file at the root of your project that `now dev` can use and extend:

```json
{
  ...
  "scripts": {
    "dev": "next --port $PORT"
  }
}
```

<Caption>
  Defining a custom <InlineCode>dev</InlineCode> script for Next.js in a{' '}
  <InlineCode>package.json</InlineCode> file.
</Caption>

<Note>
  The above script example uses <InlineCode>--port $PORT</InlineCode> in the{' '}
  <InlineCode>dev</InlineCode> command. This uses the framework's – in this case
  Next.js – port argument to pass the port from <InlineCode>now dev</InlineCode>{' '}
  so that it can properly fetch the running framework.
</Note>

### Using Environment Variables Locally

During local development with `now dev`, you may wish to provide your application with environment variables. You can find instructions on how to do this in the [environment variables and secrets section](/docs/v2/serverless-functions/env-and-secrets/#during-local-development).

## Advanced Usage

For an advanced configuration and structure, you can create a `now.json` file to use [Runtimes](/docs/runtimes) and other customizations.

We do, however, recommend using the `api` directory to keep things simple for your project.

## Technical Details

### CPU Calculation

Serverless Functions are allocated CPU power according to the amount of memory configured for them.

For example, with 1,792MB memory configured, a Serverless Function will have the equivelent of one vCPU.

## Related

For more information on what to do next, we recommend the following articles:

<Card title="Git Integration" href="/docs/v2/git-integration">
  Learn more about how ZEIT Now integrates with Git to make your workflow
  easier.
</Card>

<Card title="Using Custom Domains" href="/docs/v2/custom-domains">
  Once deployed, your projects can be assigned to a custom domain or specified
  name of your choice to give it a primary place to see the latest version of
  your application.
</Card>

export default ({ children }) => <Doc meta={meta}>{children}</Doc>

export const config = {
  amp: 'hybrid'
}
